﻿// -----------------------------------------------------------------------
// <copyright file="StringTexture.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace _0912089_0912172
{
    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class TextureUntity
    {
        private ContentManager _content;
        private GraphicsDevice _graphicsDevice;
        private Dictionary<char, int> charCodes;
        private Texture2D _texture;
        private static TextureUntity _text;
        private int _row = 7;
        private int _col = 10;
        private int _subWidth = 80;
        private int _subHeight = 140;
        private int _left = 19;
        private int _right = 19;
        private int _top = 48;
        private int _bottom = 18;
   

        private TextureUntity(ContentManager content, GraphicsDevice graphicDevice, string strTexture)
        {
            _content = content;
            _graphicsDevice = graphicDevice;
            _texture = content.Load<Texture2D>(strTexture);
            charCodes = new Dictionary<char, int>();
            charCodes.Add(' ',0);
            charCodes.Add('\'', 1);
            charCodes.Add(',', 2);
            charCodes.Add('-', 3);
            charCodes.Add('.', 4);
            charCodes.Add('/', 5);
            charCodes.Add('\\', 6);
            charCodes.Add(':', 69);

        }

        static public TextureUntity Create(ContentManager content, GraphicsDevice graphicDevice)
        {
            string str = @"Resources/System/TextTable";
            if (_text == null)
            {
                _text = new TextureUntity(content, graphicDevice, str);
            }
            
            return _text;
        }

        public int getTextWidth()
        {
            return _subWidth - _left - _right;
        }
        public Texture2D ExportStringTexture( string str)
        {
            int w = _subWidth - (_left + _right);
            int stringWidth = str.Length * w ;
            int stringHeight = _subHeight - (_top + _bottom);
            Texture2D temp = new Texture2D(_graphicsDevice, stringWidth, stringHeight);
            int d = 0;
            foreach(char ch in str.ToCharArray())
            {
                int index = getCharIndex(ch);
                Color[] dataChar = getCharData( index);
                
                temp.SetData(0, new Rectangle(d * w, 0, w, stringHeight), dataChar, 0, w * stringHeight);
                d++;
            }
            return temp;
        }
        public Texture2D horizonMerge( Texture2D tex1, Texture2D tex2)
        {
            int w = tex1.Width + tex2.Width;
            int h = tex1.Height > tex2.Height?tex1.Height : tex2.Height;

            Texture2D temp = new Texture2D(_graphicsDevice, w, h);
            Color[] dataTex1 = new Color[tex1.Width * tex1.Height];
            Color[] dataTex2 = new Color[tex2.Width * tex2.Height];

            tex1.GetData<Color>(0, new Rectangle(0, 0, tex1.Width, tex1.Height) , dataTex1, 0, tex1.Width * tex1.Height);
            tex2.GetData<Color>(0, new Rectangle(0, 0, tex2.Width, tex2.Height), dataTex2, 0, tex2.Width * tex2.Height);
            temp.SetData(0, new Rectangle(0, h - tex1.Height, tex1.Width, tex1.Height), dataTex1, 0, tex1.Width * tex1.Height);
            temp.SetData(0, new Rectangle(tex1.Width, h - tex2.Height, tex2.Width, tex2.Height), dataTex2, 0, tex2.Width * tex2.Height);

            return temp;


        }
        public Texture2D splitTexture(Texture2D texture, Rectangle rec)
        {
            
            Color[] dataTex1 = new Color[rec.Width * rec.Height];
            Texture2D temp = new Texture2D(_graphicsDevice, texture.Width, texture.Height);
            texture.GetData<Color>(0, rec, dataTex1, 0, rec.Width * rec.Height);
            temp.SetData(0, rec, dataTex1, 0, rec.Width * rec.Height);
            return temp;
        }
        public Texture2D splitTexture(Texture2D texture, double endAngle)
        {

            Color[] dataTex1 = new Color[texture.Width * texture.Height];
            Texture2D temp = new Texture2D(_graphicsDevice, texture.Width, texture.Height);
            texture.GetData<Color>(0, new Rectangle(0, 0, texture.Width , texture.Height), dataTex1, 0, texture.Width * texture.Height);
            for (int i = 1; i < texture.Height; i++)
            {
                for (int j = 1; j < texture.Width; j++)
                {
                    if ((double)(texture.Height-i) / j > Math.Tan(endAngle))
                    {
                        dataTex1[i*texture.Width+ j] = new Color(0, 0, 0, 0);
                    }
                }
            }
            temp.SetData(0, new Rectangle(0, 0, texture.Width, texture.Height), dataTex1, 0, texture.Width * texture.Height);
            return temp;
        }
        
        private int getCharIndex(char ch)
        {
            int index=0;
            if (charCodes.TryGetValue(ch,out index))
                return index;
            if (ch >= '0' && ch <= '9')
            {
                return 6 + ch - '0';
            }
            else if (ch >= 'A' && ch <= 'Z')
            {
                return 16 + ch - 'A';
            }
            return 43 + ch - 'a';
            
        }
        private Color[] getCharData( int indx)
        {
            return getCharData( indx / _col, indx % _col);
        }
        public Texture2D createTexture(int w,int h,Color color)
        {
            Texture2D texture = new Texture2D(_graphicsDevice, w, h);
            Color[] data = new Color[w * h];
            for (int i = 0; i < data.Length; i++)
                data[i] = color;
            texture.SetData(data);
            return texture;
        }

        public Texture2D createTexture(int w, int h,int d, Color color)
        {
            Texture2D texture = new Texture2D(_graphicsDevice, w, h);
            Color[] data = new Color[w * h];
            for (int i = 0; i < data.Length; i++)
                if (i / w + i % w > d && h - i / w + w-i % w > d)
                {
                    data[i] = color;
                }
            texture.SetData(data);
            return texture;
        }
        public Texture2D ExportCharTexture(int rowIdx, int colIdx)
        {
            int h = _subHeight - (_top + _bottom);
            int w = _subWidth - (_left + _right);
            Texture2D result = new Texture2D(_graphicsDevice, w, h);
            Color[] data = new Color[w * h];
            _texture.GetData<Color>(0,
                new Rectangle(colIdx * _subWidth + _left, rowIdx * _subHeight + _top, w, h)
                , data, 0, w * h);
            result.SetData(0, new Rectangle(0, 0, w, h), data, 0, w * h);
            return result;
        }
        private Color[] getCharData( int rowIdx, int colIdx)
        {
            int h = _subHeight - (_top + _bottom);
            int w = _subWidth - (_left + _right);
 
            Color[] data = new Color[w * h];
            _texture.GetData<Color>(0,
                new Rectangle(colIdx * _subWidth + _left, rowIdx * _subHeight + _top, w, h)
                , data, 0, w * h);
            return data;
        }



    }
}
